(function(window){
    "use strict";
    var Backbone = window.Backbone, vita = window.vita;
    if(!Backbone || !vita){
        return;
    }
    /********* vita的backbone封装  ***********/
    vita.Backbone = {};

    /**************** vita的backbone的model基类   **************/
    vita.Backbone.Model = Backbone.Model.extend();

    /********* vita的backbone的view基类  ************/
    //增加template、gSession、assist、end
    var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events', "template", "gSession", "assist", "end"];
    var View = function(options, target){
        /**
         * 用来覆盖backbone的view构造行数
         * 增加：
         * 1、this.super(父类)
         * 2、this.vid（vita管理器的唯一标识）
         * 3、target入参（已有的html元素，可以是jquery对象）
         * 4、_initElement(给指定元素初始化一些属性)
         */
        this.cid = _.uniqueId('vita');
        _.extend(this, _.pick(options, viewOptions));
        if(target){
            this.el = target;
        }
        this.vid = this.cid;
        this.super = this.constructor.__super__;
        this._ensureElement();
        this._initElement();
        this.initialize.apply(this, arguments);
    };
    View.prototype = {
        //新增：单例模式，此处默认多例，只读
        // get singleton(){
        //     return false;
        // },
        singleton : false,
        //设置组件元素必要信息
        _initElement : function(){
            if(this.el){
                $(this.el).attr({"data-vid":this.vid,"data-widgetFullName":this.widgetFullName});
            }
        },
        //构造函数
        constructor : View,
        initialize : function(){
            this._initialize();
        },
        _initialize : vita.noop,
        //模版
        template : null,
        //求值，处理模版和数据模型
        evaluate : vita.noop,
        //新增：销毁方法，含组件自定义销毁逻辑，和backbone的view的remove逻辑
        destroy : function(){
            //组件模块内部销毁前动作
            this._destroy();
            //删除绑定的事件侦听
            vita.event.removeListener(this);
            //删除实例
            vita.widget.self("removeInstance", this.widgetName, this.vid);
            //backbone自身删除
            this.remove();
        },
        _destroy : vita.noop,
        //新增：模块请求
        require : vita.widget.require,
        widgetName : null,
        getWidgetName : function () {
            return this.widgetName;
        }
    };
    vita.Backbone.View = Backbone.View.extend(View.prototype);
})(window);
(function(window){
    "use strict";
    //如果vita为空，或者vita下已经生成Backbone节点，则不再初始化
    var vita = window.vita;
    if (!vita || (vita.Backbone ? vita.Backbone.BizView : true)){
        return;
    }
    /********* vita的业务组件模型  ************/
    vita.Backbone.BizModel = vita.Backbone.Model.extend();

    /********* vita的业务组件视图  ************/
        //生成biz类
    vita.Backbone.BizView = vita.Backbone.View.extend({
        //服务路径
        servicePath : "$servicePath",
        //是否需要路由
        isRoute : true,
        //session
        gSession : $gSession,
        _newModel : function () {
            return new vita.Backbone.BizModel();
        },
        _scanHtmlTag : function (el, type) {
            var checkFun, htmlTag = this.require("htmlTag"), model = this.model, element = this.el, types;
            type = type || "data,bind", types = type.split(",");
            if(!el){
                el = $(this.el);
                checkFun = function (ele) {
                    return element == ele.closest("[data-widget]")[0];
                };
            }
            if(!model){
                model = this.model = this._newModel();
            }
            for(var t in types){
                switch (types[t]){
                    case "data" :
                        htmlTag.data(el, checkFun);
                        break;
                    case "bind" :
                        htmlTag.bind(el, function (key, value) {
                            model.set(key, value);
                        }, function (key, callBack) {
                            model.bind("change:" + key, function () {
                                callBack(arguments[1]);
                            });
                        }, checkFun);
                        break;
                }
            }
        },
        //初始化
        initialize : function(){
            //this.super.initialize();
            //准备好servicePath
            if(this.servicePath != null && this.servicePath.charAt(this.servicePath.length - 1) != "/"){
                this.servicePath += "/";
            }
            this._scanHtmlTag();
            this._initialize();
        },
        //model和view合并执行器
        evaluate : function(){
            if(this.template){
                var t = _.template(this.template);
                $(this.el).html(t(this.model.toJSON()));
            }
        },
        //协助
        assist : function(flag, data, cb){
            return [[flag, data, true], [cb, this]];
        },
        //结束
        end : function (flag, data) {
            return [[flag, data, true]];
        },
        //获取组件的值
        getValue : vita.noop,
        //获取el
        getElement : function(){
            return $(this.el);
        },
        //组件局部刷新方法
        refreshPart : function(methodName, params, selector, keyName, callBack, options){
            var widget = this, element = $(widget.el), url = this.servicePath + "refreshPart";
            if(typeof keyName === "function"){
                options = callBack;
                callBack = keyName;
                keyName = null;
            }
            /**  处理请求参数 start **/
            params = local.dealParams(params);
            /**  处理请求参数 end **/
            var inParams = {
                widgetName : widget.widgetName,
                methodName : methodName,
                params : JSON.stringify(params),
                selector : selector,
                keyName : keyName
            };
            if(widget.isRoute){
                inParams.routeParam = widget.gSession.staffAreaId;
            }
            vita.ajax(url, inParams, function(re){
                re = $(re);
                //处理data
                widget._scanHtmlTag(re, "data");
                //销毁原有组件
                var tar = element.find(selector);
                local.destroyWidgets(tar);
                //回调函数
                if($.isFunction(callBack)){
                    callBack.call(widget,re[0]);
                }
                //更新内容
                //tar.empty().replaceWith(re);
                tar.empty().append(re.contents());
                local.initWidgets();
            }, options);
        },
        increasePart : function(methodName, params, selector, keyName, callBack, options){
            var widget = this, element = $(widget.el), url = this.servicePath + "refreshPart";
            if(typeof keyName === "function"){
                options = callBack;
                callBack = keyName;
                keyName = null;
            }
            /**  处理请求参数 start **/
            params = local.dealParams(params);
            /**  处理请求参数 end **/
            var inParams = {
                widgetName : widget.widgetName,
                methodName : methodName,
                params : JSON.stringify(params),
                selector : selector,
                keyName : keyName
            };
            if(widget.isRoute){
                inParams.routeParam = widget.gSession.staffAreaId;
            }
            vita.ajax(url, inParams, function(re){
                re = $(re);
                //处理data
                widget._scanHtmlTag(re, "data");
                //回调函数
                if($.isFunction(callBack)){
                    callBack.call(widget,re[0]);
                }
                //增加内容
                element.find(selector).append(re.contents());
                local.initWidgets();
            }, options);
        },
        //组件刷新方法
        refreshView : function(params, callBack, options){
            var widget = this, element = $(widget.el), url = this.servicePath + "refreshView";
            /**  校验方法入参 start **/
            if(vita.self("isFunction", params)){
                //如果第一个入参是函数，判定为将调用的刷新方法木有入参，判定第一个入参为回调函数
                options = callBack;
                callBack = params;
                params = null;
            }
            /**  校验方法入参 end **/

            /**  处理请求参数 start **/
            params = local.dealParams(params);
            /**  处理请求参数 end **/
            var inParams = {
                widgetName : widget.widgetName,
                params : JSON.stringify(params)
            };
            if(widget.isRoute){
                inParams.routeParam = widget.gSession.staffAreaId;
            }
            vita.ajax(url, inParams, function(re){
                re = $(re);
                //处理data
                widget._scanHtmlTag(re, "data");
                //销毁原组件
                local.destroyWidgets(element);
                //回调函数
                if($.isFunction(callBack)){
                    callBack.call(widget,re[0]);
                }
                //更新内容
                //element.empty().replaceWith(re);
                element.empty().append(re.contents());
                local.initWidgets();
            }, options);
        },
        //调用数据对象服务
        callService : function(methodName, params, callBack, options){
            var widget = this, url = this.servicePath + "callService";
            /**  校验方法入参 start **/
            if(!vita.self("isString", methodName)){
                //如果methodName不是字符串，提示，返回
                widget.popup("第一个入参必须是字符串，代表需要调用的方法名！");
                return false;
            }
            if(vita.self("isFunction", params)){
                //如果第二个入参是函数，判定为将调用的方法木有入参，判定第二个入参为回调函数
                callBack = params;
                params = null;
            }
            /**  校验方法入参 end **/

            /**  处理请求参数 start **/
            params = local.dealParams(params);
            /**  处理请求参数 end **/
            var inParams = {
                widgetName : widget.widgetName,
                methodName : methodName,
                params : JSON.stringify(params)
            };
            if(widget.isRoute){
                //需要路由
                inParams.routeParam = widget.gSession.staffAreaId;
            }
            vita.ajax(url, inParams, function(re){
                if($.isFunction(callBack)){
                    callBack.call(widget,re);
                }
            }, options);
        },
        //更新session
        refreshSession : function(session){
            $.extend(this.gSession, session);
            vita.ajax(this.servicePath + "refreshSession", session, {async : false});
        },
        //清空session
        removeSession : function(){
            this.gSession = {};
            vita.ajax(this.servicePath + "removeSession");
            //派发事件
            this.dispatchEvent("removeParty");
        },
        //刷新session里的客户信息
        refreshParty : function(party, reset){
            var eParty = {};
            //修正areaId和areaName
            for(var key in party){
                if(key == "areaId"){
                    eParty.partyAreaId = party[key];
                }else if(key == "areaName"){
                    eParty.partyAreaName = party[key];
                }else if(key == "identityCd"){
                    eParty.identidiesTypeCd = party[key];
                }else {
                    eParty[key] = party[key];
                }
            }
            if(reset){
                eParty.reset = true;
                local.removeParty(this.gSession);
            }
            $.extend(this.gSession, eParty);
            vita.ajax(this.servicePath + "refreshParty", eParty, {async : false});
            //派发事件
            this.dispatchEvent("refreshParty", eParty);
        },
        //清空session里的客户信息
        removeParty : function(){
            local.removeParty(this.gSession);
            vita.ajax(this.servicePath + "removeParty");
            //派发事件
            this.dispatchEvent("removeParty");
        },
        //增加事件侦听
        addListener : function(eventName, func){
            vita.event.addListener(this, eventName, func);
        },
        //删除事件侦听
        removeListener : function(eventName, func){
            vita.event.removeListener(this, eventName, func);
        },
        //派发事件
        dispatchEvent : function(widget, eventName){
            //vita.event.dispatchEvent(widget, eventName);
            vita.event.dispatchEvent.apply(vita.event, arguments);
        },
        //新增：提示
        popup : function(info, baseFunction, extFunction){
            var el;
            vita.router.addLimit();
            if(arguments.length >= 3){
                //confirm
                el = local.newConfirm(null, info, baseFunction, extFunction);
            }else{
                //alert
                el = local.newAlert(null, info, baseFunction);
            }
            $("body").append(el);
        },
        //对话框
        dialog : function(id){
            if(typeof id === "string"){
                id = this.widgetName + "_" + id;
                var sid = $("body").find(id);
                if(sid.length > 0){
                    vita.router.addLimit();
                    sid.dialog("open");
                }
                return sid.length;
            }else if(typeof id === "object"){
                if(id.id){
                    id.id = this.widgetName + "_" + id.id;
                }
                vita.router.addLimit();
                var d = local.newDialog(id);
                $("body").append(d.getElement());
                return 1;
            }else{
                return 0;
            }
        }
    });

    var local = {
        //参数处理
        dealParams : function(params){
            if(!params){
                params = [];
            }else if(!$.isArray(params)){
                params = [params];
            }
            for(var i=0;i < params.length;i++){
                //如果不是字符串要全部转成字符串
                if(typeof params[i] != "string"){
                    params[i] = JSON.stringify(params[i]);
                }
            }
            return params;
        },
        //初始化组件
        initWidgets : function(){
            var objs = $("body").find("[data-widget]:not([data-vid])");
            for(var i = objs.length - 1;i >= 0; i--){
                var o = $(objs[i]), template = o.attr("data-widget");
                var view = vita.widget.require(template);
                if(view){
                    var model = vita.widget.require(template + "_model");
                    var options = {
                        el : o
                    };
                    if(model != null){
                        options.model = model["new"]();
                    }
                    view["new"](options);
                }
            }
        },
        //销毁组件
        destroyWidgets : function(tar){
            var widgets = tar.find("[data-vid]");
            widgets.each(function(i, w){
                var ww = $(w), name = ww.attr("data-widgetfullname").split("-")[1];
                if($.isFunction(ww[name])){
                    ww[name]("destroy");
                }
            });
        },
        //清除session中的客户信息
        removeParty : function(gSession){
            gSession.partyId = null;
            gSession.partyName = null;
            gSession.identidiesTypeCd = null;
            gSession.identityName = null;
            gSession.idCardNumber = null;
            gSession.partyAreaId = null;
            gSession.partyAreaName = null;
            gSession.authTypeCd = null;
            gSession.authNumber = null;
            gSession.acctCd = null;
            gSession.extPartyId = null;
            gSession.acctSecGroup = null;
            gSession.acctThreeGroup = null;
            gSession.acctFourGroup = null;
        },
        //alert
        newAlert : function(title, msg, func){
            var popup = vita.widget.require("popup");
            return popup.new({
                text : msg,
                buttons : [{
                    text : "我知道了",
                    click : func
                }],
                onClose : function(){
                    vita.router.delLimit();
                },
                onCancel : func
            }).getElement();
        },
        //confirm
        newConfirm : function(title, msg, confirm, cancel){
            var popup = vita.widget.require("popup");
            return popup.new({
                text : msg,
                buttons : [{
                    text : "取消",
                    click : cancel
                },{
                    text : "确定",
                    click : confirm,
                    class : "btnblockfull"
                }],
                onClose : function(){
                    vita.router.delLimit();
                },
                onCancel : cancel
            }).getElement();
        },
        //dialog
        newDialog : function(options){
            var dialog = vita.widget.require("dialog");
            //处理参数 start
            if(typeof options.params != "object"){
                options.params = {};
            }
            options.params.inFrame = true;
            //在onClose方法里加入逻辑
            if(options.onClose && vita.self("isFunction", options.onClose)){
                vita.aop.after("onClose",function(){
                    vita.router.delLimit();
                },options);
            }else{
                options.onClose = function(){
                    vita.router.delLimit();
                };
            }
            //处理参数 end
            return dialog.new(options);
        }
    };

    //模块集合组件类
    //var assemble = vita.Backbone.BizView.extend({});
    //定义widgetName的读写方法，用来获取在该容器内的场景名称，Backbone的extend不支持get、set
    // Object.defineProperties(assemble.prototype,{
    //     widgetName : {
    //         get : function(){
    //             return $(this.el).attr("data-assistName");
    //         },
    //         set : function(){}
    //     }
    // });
    var assemble = vita.Backbone.BizView.extend({
        getWidgetName : function () {
            return $(this.el).attr("data-assistName");
        }
    });
    vita.widget.register("assemble", assemble, true);
})(window);